import { contextMenu } from './context-menu-config';
import { cloneDeep } from 'lodash-es';
import { BsModalService } from '@farris/ui-modal';
import { ComponentFactoryResolver } from '@angular/core';
import FdContainerBaseComponent from '../../common/containerBase/containerBase';
import { RowNode } from '@farris/ui-treetable';
import { ContextMenuManager } from '../../../../service/context-menu.manager';
import { ControlContextMenuItem } from '../../../../entity/control-context-menu';
import { SplitFormComponent } from './editor/split-form-component/split-form-component.component';
import { SchemaService, ComponentBindingSourceContext, ComponentResolveContext, DgControl } from '@farris/designer-services';
import { DragResolveService } from '@farris/designer-devkit';
import { TableComponentCreatorContextMenuService } from './services/table-creator.service';


export class ComponentContextMenuManager extends ContextMenuManager {

    private modalService: BsModalService;
    private schemaService: SchemaService;

    constructor(cmp: FdContainerBaseComponent, rowNode: RowNode) {
        super(cmp, rowNode);

        this.modalService = this.serviceHost.getService('ModalService');
        this.schemaService = this.injector.get(SchemaService);
    }
    /**
     * 过滤、修改控件树右键菜单
     */
    setContextMenuConfig() {
        let menuConfig = cloneDeep(contextMenu) as ControlContextMenuItem[];

        menuConfig = this.assembleFormCmpMenu(menuConfig);

        // 配置菜单点击事件
        this.addContextMenuHandle(menuConfig);

        return menuConfig || [];
    }

    /**
     * 点击控件树右键菜单
     */
    contextMenuClicked(e: { data: RowNode, menu: ControlContextMenuItem }) {

        const menu = e.menu;

        if (menu.parentMenuId === 'addSiblingContent') {
            this.addSiblingComponent(menu.id);
            return;
        }
        switch (menu.id) {
            case 'splitFormComponent': {
                this.splitFormComponent();
                return;
            }
            case 'changeFormToTableComponent': {
                this.changeFormComponentToTableComponent();
                return;
            }
        }
        this.notifyService.warning('暂不支持');
    }

    private assembleFormCmpMenu(menuConfig: ControlContextMenuItem[]) {

        // 目前只支持卡片组件添加同级、拆分组件、切换为table
        const cmpType = this.cmpInstance.component.componentType;
        if (cmpType && cmpType.startsWith('form')) {
            menuConfig = this.assembleChangeFormToTableMenu(menuConfig);
            return menuConfig;
        }

        return [];
    }
    /**
     * 添加同级组件
     * @param menuItem 菜单配置
     */
    addSiblingComponent(menuId: string) {
        // 目前只支持卡片
        if (menuId !== 'Form') {
            return;
        }
        const dragResolveService = this.injector.get(DragResolveService);
        const componentResolveContext = new ComponentResolveContext();
        componentResolveContext.controlType = this.cmpInstance.component.componentType;

        const bandingEntityInfo = this.schemaService.getTableInfoByViewModelId(this.cmpInstance.viewModelId);
        if (bandingEntityInfo) {
            componentResolveContext.needExcludeDisplayedFields = true;
            componentResolveContext.bindingTargetId = bandingEntityInfo.id;
            componentResolveContext.bindingTargetInSidebar = this.checkComponentIfInSidebar(this.cmpInstance.id);

            dragResolveService.triggerBindingEntity(componentResolveContext).subscribe(
                (componentBindingSourceContext: ComponentBindingSourceContext) => {
                    if (componentBindingSourceContext) {
                        this.insertComponent(componentBindingSourceContext);
                        this.refreshFormService.refreshFormDesigner.next();
                    }

                });
        } else {
            this.notifyService.error('查询绑定实体失败');
        }


    }
    /**
     * 将组件相关节点插入DOM
     * @param componentBindingSourceContext 组件构造信息
     * @param componentRefParentNode 组件引用节点的父节点
     */
    private insertComponent(componentBindingSourceContext: ComponentBindingSourceContext) {
        const { componentNode, componentRefNode, viewModelNode } = componentBindingSourceContext;

        // 定位ComponentRef的父级节点
        const cmpRefId = this.cmpInstance.parent && this.cmpInstance.parent.id;

        const cmpRefParentContainerCmp = this.cmpInstance.parent && this.cmpInstance.parent.parent;
        const cmpRefParentContainerElement = cmpRefParentContainerCmp && cmpRefParentContainerCmp.component;
        if (!cmpRefParentContainerElement) {
            return;
        }

        const currentElementIndex = cmpRefParentContainerElement.contents.findIndex(el => el.id === cmpRefId);
        if (currentElementIndex > -1) {

            // 插入ComponentRef节点
            cmpRefParentContainerElement.contents.splice(currentElementIndex + 1, 0, componentRefNode);

            // 插入Component和ViewModel
            this.domService.addComponent(componentNode);
            this.domService.addViewModel(viewModelNode);
        }
    }

    /**
     * 拆分Form组件
     */
    splitFormComponent() {
        const resolver = this.injector.get(ComponentFactoryResolver);
        const compFactory = resolver.resolveComponentFactory(SplitFormComponent);
        const compRef = compFactory.create(this.injector);

        const modalConfig = {
            title: '拆分组件',
            width: 900,
            height: 600,
            showButtons: true,
            buttons: compRef.instance.modalFooter
        };

        compRef.instance.schemaDOMMapping = this.serviceHost.getService('SchemaDOMMapping');
        compRef.instance.componentId = this.cmpInstance.componentId;
        compRef.instance.componentParentContainerId = this.cmpInstance.parent.parent.id;

        const modalPanel = this.modalService.show(compRef, modalConfig);
        compRef.instance.closeModal.subscribe(() => {
            modalPanel.close();
        });

        compRef.instance.submitModal.subscribe(() => {
            this.refreshFormService.refreshFormDesigner.next();
            modalPanel.close();
        });
    }

    /**
     * 组装form切换为table的菜单
     */
    private assembleChangeFormToTableMenu(menuConfig: ControlContextMenuItem[]): ControlContextMenuItem[] {

        const tableCreatorServ = new TableComponentCreatorContextMenuService(this.injector, this.cmpInstance);
        return tableCreatorServ.assembleChangeFormToTableMenu(menuConfig);

    }
    /**
     * 将卡片组件切换为table组件
     */
    private changeFormComponentToTableComponent() {

        const tableCreatorServ = new TableComponentCreatorContextMenuService(this.injector, this.cmpInstance);
        tableCreatorServ.changeFormComponentToTableComponent();

    }

    /**
     * 检查卡片组件是否在侧边栏中，在侧边栏中的字段可以与非侧边栏中的字段重复。
     */
    private checkComponentIfInSidebar(cmpNodeId: string) {

        const sidebar = this.domService.selectNode(this.domService.components[0],
            item => item.type === DgControl.Sidebar.type && item.contents && item.contents.length &&
                item.contents.find(child => child.type === DgControl.ComponentRef.type && child.component === cmpNodeId));
        if (sidebar) {
            return true;
        }
        return false;
    }

}

